home *** CD-ROM | disk | FTP | other *** search
/ Night Owl 6 / Night Owl's Shareware - PDSI-006 - Night Owl Corp (1990).iso / 007a / cug317.zip / G3TDECOD.C < prev    next >
C/C++ Source or Header  |  1990-06-18  |  9KB  |  300 lines

  1. /*    $Id: g3tdecod.c 1.2 90/06/09 18:23:04 marking Exp $
  2.  *
  3.  NAME
  4.  *    g3tdecod.c -- decode group 3 data using tables
  5.  *
  6.  TYPE
  7.  *    C procedures
  8.  *
  9.  SYNOPSIS
  10.  *    char    g3i_initialize (short image_width, short image_length);
  11.  *    char    g3i_decode (void);    -- for standard group 3
  12.  *    char    g3i_decode_T (void);    -- for TIFF g3 with no EOL chars
  13.  *
  14.  DESCRIPTION
  15.  *    In order to acquire data from the image and to return run lengths and
  16.  *    new line information, these routines invoke procedures provided by the
  17.  *    caller. These caller-provided procedures are invoked throught pointers
  18.  *    which have been stuffed by the caller with the procedure addresses.
  19.  *    To acquire a new data byte, g3i_decode () and g3i_decode_T () call
  20.  *    (*p_decode_next_byte) (). To report the decoding of a black or white
  21.  *    run, the routines (*p_decode_black) () or (*p_decode_white) () are
  22.  *    called.
  23.  *
  24.  RETURNS
  25.  *    Initialization always returns zero.
  26.  *
  27.  *    For decoding,
  28.  *        0    end of image reached
  29.  *        -1    on error (bad data)
  30.  *    The decode loop will be prematurely terminated if decode_return is
  31.  *    set to not zero, and the value of decode_return will be returned.
  32.  *    No code here does this, but it might be useful under certain
  33.  *    circumstances.
  34.  *
  35.  LEGAL
  36.  *    Copyright 1989, 1990 Michael P. Marking, Post Office Box 8039,
  37.  *    Scottsdale, Arizona 85252-8039. All rights reserved.
  38.  *
  39.  *    License is granted by the copyright holder to distribute and use this
  40.  *    code without payment of royalties or the necessity of notification as
  41.  *    long as this notice (all the text under "LEGAL") is included.
  42.  *
  43.  *    Reference: $Id: g3tdecod.c 1.2 90/06/09 18:23:04 marking Exp $
  44.  *
  45.  *    This program is offered without any warranty of any kind. It includes
  46.  *    no warranty of merchantability or fitness for any purpose. Testing and
  47.  *    suitability for any use are the sole responsibility of the user.
  48.  * 
  49.  HISTORY
  50.  *    $Log:    g3tdecod.c $
  51.  * Revision 1.2  90/06/09  18:23:04  marking
  52.  * clean up comments for release
  53.  * 
  54.  * Revision 1.1  89/06/30  17:00:00  marking
  55.  * Initial revision
  56.  * 
  57.  *
  58.  NOTES
  59.  *
  60.  PORTABILITY
  61.  *    Tested using Microsoft C 5.1. Some memory models may not work due to
  62.  *    the large decoding arrays.
  63.  *
  64.  *    There is a non-portable use of "global" variables in the file g3g4.h,
  65.  *    about which a minority of compilers will justifiably complain. Certain
  66.  *    variables are declared in g3g4.h without extern keywords. Strictly
  67.  *    speaking, they should be declared extern in all but one module, but
  68.  *    that would require complication of g3g4.h. If it gets past your
  69.  *    compiler and linker, you can probably ignore it.
  70.  *
  71.  SEE ALSO
  72.  *    g4tdecod.c -- decode group 4 image using tables
  73.  *    builddec.c -- build image decoding tables
  74.  *
  75.  INFORMATION
  76.  *    Although there is no support offered with this program, the author will
  77.  *    endeavor to correct errors. Updates will also be made available from
  78.  *    time to time.
  79.  *
  80.  *    Contact: Michael P. Marking, Post Office Box 8039, Scottsdale, Arizona
  81.  *    85252-8039 USA. Replies are not guaranteed to be swift. Beginning
  82.  *    July 1990, e-mail may be sent to uunet!ipel!marking.
  83.  *
  84.  *    Also beginning in July 1990, this code will be archived at the
  85.  *    ipel!phoenix BBS in file g3g4.zoo. The 24-hour telephone number
  86.  *    for 300/1200/2400 is (602)274-0462. When logging in, specify user
  87.  *    "public", system "bbs", and password "public".
  88.  *
  89.  *    This code is also available from the C Users Group in volume 317.
  90.  */
  91.  
  92. #include "g3g4.h"
  93.  
  94. /* #define TRACE 1 */
  95. #define TRACE_BEGIN 0
  96. #define TRACE_END 30000
  97.  
  98. static short bit_number, code_byte;
  99. static unsigned char color, current_row, mode, next_state;
  100. static short column_limit, row_limit;
  101. static short row_number = 0, column_number;
  102.  
  103. extern unsigned char huge horiz_mode [] [256];
  104. extern unsigned char huge horiz_mode_next_state [] [256];
  105.  
  106. static short new_row (void);
  107. static short decode_white_run (void);
  108. static short decode_black_run (void);
  109.  
  110. static char decode_return;
  111.  
  112. /* g3i_decode () successively invokes (*p_decode_next_byte) () for each byte of the
  113.    encoded image, and calls (*p_decode_white) () or (*p_decode_black) () as
  114.    required to return the image contents on a run-by-run basis. */
  115.  
  116. char g3i_decode ()
  117. {
  118.   short runlength;
  119.   while (!decode_return)
  120.   {
  121.     if (color == WHITE)
  122.     {
  123.       runlength = decode_white_run ();
  124.       if (runlength == -2) return (-1);
  125.       else if (runlength == -1)
  126.       {
  127.     if (new_row ()) return (0);
  128.       }
  129.       else
  130.       {
  131.     column_number += runlength;
  132.     (*p_decode_white) ((short) runlength);
  133.     color = BLACK;
  134.       }
  135.     }
  136.     else
  137.     {
  138.       runlength = decode_black_run ();
  139.       if (runlength == -2) return (-1);
  140.       else if (runlength == -1)
  141.       {
  142.     if (new_row ()) return (0);
  143.       }
  144.       else
  145.       {
  146.     column_number += runlength;
  147.     (*p_decode_black) ((short) runlength);
  148.     color = WHITE;
  149.       }
  150.     }
  151.   }
  152.   return (decode_return);
  153. }
  154.  
  155. /* special version for TIFF files with no EOL characters */
  156. char g3i_decode_T ()
  157. {
  158.   short runlength;
  159.   while (!decode_return)
  160.   {
  161.     if (color == WHITE)
  162.     {
  163.       runlength = decode_white_run ();
  164.       if (runlength == -2) return (-1);
  165.       else if (runlength == -1)
  166.       {
  167.     if (new_row ()) return (0);
  168.       }
  169.       else
  170.       {
  171.     column_number += runlength;
  172.     (*p_decode_white) ((short) runlength);
  173.     color = BLACK;
  174.     if (column_number >= column_limit)
  175.     {
  176.       if (new_row ()) return (0);
  177.       bit_number = 0;
  178.     }
  179.       }
  180.     }
  181.     else
  182.     {
  183.       runlength = decode_black_run ();
  184.       if (runlength == -2) return (-1);
  185.       else if (runlength == -1)
  186.       {
  187.     if (new_row ()) return (0);
  188.       }
  189.       else
  190.       {
  191.     column_number += runlength;
  192.     (*p_decode_black) ((short) runlength);
  193.     color = WHITE;
  194.     if (column_number >= column_limit)
  195.     {
  196.       if (new_row ()) return (0);
  197.       bit_number = 0;
  198.     }
  199.       }
  200.     }
  201.   }
  202.   return (decode_return);
  203. }
  204.  
  205. /* g3i_initialize () is called to set up to decode a new image.  All of the
  206.    static data (flags, etc) for g3i_decode () are initialized, allowing the
  207.    decoding of multiple images as long as g3i_initialize () is
  208.    called before each. */
  209. char g3i_initialize (short image_width, short image_length)
  210. {
  211.   color = WHITE;
  212.   bit_number= 0;
  213.   column_limit = image_width;
  214.   row_limit = image_length;
  215.   row_number = 0;
  216.   column_number = 0;
  217.   decode_return = 0;
  218.   return (0);
  219. }
  220.  
  221. static short new_row ()
  222. {
  223.   if (column_number)
  224.   {
  225.     (*p_decode_new_row) ();
  226.     color = WHITE;
  227.     if (++row_number >= row_limit) return (-1);
  228.     column_number = 0;
  229.     return (0);
  230.   }
  231.   else return (0);
  232. }
  233.  
  234. static short run_length_table [] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
  235.   13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
  236.   32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
  237.   51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 128, 192, 256, 320,
  238.   384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1024, 1088, 1152, 1216,
  239.   1280, 1344, 1408, 1472, 1536, 1600, 1664, 1728, 1792, 1856, 1920, 1984,
  240.   2048, 2112, 2176, 2240, 2304, 2368, 2432, 2496, 2560};
  241.  
  242. static short decode_black_run ()
  243. {
  244.   short runlength, accum_runlength = 0;
  245.   next_state = (unsigned char) (bit_number + 8);
  246.   for (;;) /* exit with "return" */
  247.   {
  248.     if (!bit_number) code_byte = (*p_decode_next_byte) ();
  249.       /* this will fetch a new byte
  250.         if the previous codeword ended on a byte boundary */
  251.     mode = horiz_mode [next_state] [code_byte];
  252.     next_state = horiz_mode_next_state [next_state] [code_byte];
  253.     if (mode == 1) return (-2); /* invalid code */
  254.     else if (mode == 210)
  255.     {
  256.       bit_number = next_state;
  257.       return (-1);
  258.     }
  259.     else if (mode) /* if digestible */
  260.     {
  261.       bit_number = next_state;
  262.       runlength = run_length_table [mode - 106];
  263.       accum_runlength += runlength;
  264.       if (runlength < 64) return (accum_runlength);
  265.       next_state += 8;
  266.     }
  267.     else bit_number = 0;
  268.   }
  269. }
  270.  
  271. static short decode_white_run ()
  272. {
  273.   short runlength, accum_runlength = 0;
  274.   next_state = (unsigned char) bit_number;
  275.   for (;;) /* exit with "return" */
  276.   {
  277.     if (!bit_number) code_byte = (*p_decode_next_byte) ();
  278.       /* this will fetch a new byte
  279.         if the previous codeword ended on a byte boundary */
  280.     mode = horiz_mode [next_state] [code_byte];
  281.     next_state = horiz_mode_next_state [next_state] [code_byte];
  282.     if (mode == 1) return (-2); /* invalid code */
  283.     else if (mode == 210)
  284.     {
  285.       bit_number = next_state;
  286.       return (-1);
  287.     }
  288.     else if (mode) /* if digestible */
  289.     {
  290.       bit_number = next_state;
  291.       runlength = run_length_table [mode - 2];
  292.       accum_runlength += runlength;
  293.       if (runlength < 64) return (accum_runlength);
  294.     }
  295.     else bit_number = 0;
  296.   }
  297. }
  298.  
  299. /*    end $RCSfile: g3tdecod.c $ */
  300.